import IDBManager from './engine/indexed-db'
import StorageSpace from './engine/storage-space'
import { StorageType, StorageKey, ChatStoreName } from './enum'

// 本地存取服务
const localStorage = new StorageSpace(StorageType.Local)
const sessionStorage = new StorageSpace(StorageType.Session)

/**
 * Storage Provider 实现调用类
 */
class StorageProvider {
  /**
   * 读取 localStorage
   *
   * @param key 键
   * @param defaultValue 默认值
   * @returns
   */
  public static getLocalStorage = <T>(key: StorageKey, defaultValue?: T) => {
    return localStorage.getItem<T>(key) ?? defaultValue
  }
  /**
   * 写入 localStorage
   *
   * @param key 键
   * @param value 值（传入null删除）
   * @returns
   */
  public static setLocalStorage = <T>(key: StorageKey, value: T) => {
    if (value === null) {
      // 清空数据
      localStorage.removeItem(key)
    } else {
      localStorage.setItem<T>(key, value)
    }
  }
  /**
   * 读取 sessionStorage
   *
   * @param key 键
   * @param defaultValue 默认值
   * @returns
   */
  public static getSessionStorage = <T>(key: StorageKey, defaultValue?: T) => {
    return sessionStorage.getItem<T>(key) ?? defaultValue
  }
  /**
   * 写入 sessionStorage
   *
   * @param key 键
   * @param value 值（传入null删除）
   * @returns
   */
  public static setSessionStorage = <T>(key: StorageKey, value: T) => {
    if (value === null) {
      sessionStorage.removeItem(key)
    } else {
      sessionStorage.setItem<T>(key, value)
    }
  }
  /**
   * 初始化聊天数据库
   *
   * @param store 存储名称
   * @returns
   */
  public static DBChatInstance = async <T>(store: ChatStoreName) => {
    const stores = Object.values(ChatStoreName).map((name) => ({ name }))
    const DB = await IDBManager.getInstance('local-chat', 1, stores)
    return {
      /** 获取全部数据 */
      getAll: () => DB.getAll<T>(store),
      /** 获取单个数据 */
      get: (key: IDBValidKey) => DB.get<T>(store, key),
      /** 新增&更新数据 */
      set: (data: T | T[]) => DB.set<T>(store, data),
      /** 删除数据 */
      delete: (key: IDBValidKey | IDBValidKey[]) => DB.delete(store, key),
      /** 清空数据 */
      clear: () => DB.clear(store),
    }
  }
  /**
   * 清空所有本地存储
   */
  public static clearAll = async () => {
    localStorage.clear()
    sessionStorage.clear()
    if (window.indexedDB && indexedDB.databases) {
      const dbs = await indexedDB.databases()
      for (const db of dbs) {
        if (db.name) {
          indexedDB.deleteDatabase(db.name)
        }
      }
    } else {
      // Fallback for browsers without indexedDB.databases()
      // You may need to know the DB names to delete them explicitly
      // Or skip if not supported
    }
  }
}

export default StorageProvider
